home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
1992
/
07
/
filter.asc
< prev
next >
Wrap
Text File
|
1992-06-15
|
20KB
|
462 lines
_GRAPHICS IMPORT FILTERS FOR WINDOWS APPLICATIONS_
by Evangelo Prodromou
[LISTING ONE]
/****************************************************************************
FILE : Viewer.h
PURPOSE: header file for graphic viewer
(C) 1992, Evangelo Prodromou. All rights reserved.
****************************************************************************/
/* Viewer Menu item definitions */
#define IDM_ABOUT 100
#define IDC_STATIC -1
/* general-use string size. */
#define STRINGSIZE 511
/* The following definitions are data types defined by the Aldus Interface. */
typedef DWORD FILETYPE;
typedef struct {
unsigned slippery : 1; /* TRUE if file may disappear. */
unsigned write : 1; /* TRUE if open for write. */
unsigned unnamed : 1; /* TRUE if unnamed. */
unsigned linked : 1; /* Linked to an FS FCB. */
unsigned mark : 1; /* Generic mark bit. */
FILETYPE fType; /* The file type. */
#define IBMFNSIZE 124
short handle; /* MS-DOS open file handle. */
char fullName[IBMFNSIZE]; /* Device, path, file names. */
DWORD filePos; /* Our current file posn. */
} FILESPEC, FAR *LPFILESPEC;
typedef short DC;
typedef struct { /* --- PICTINFO for Windows --- */
HANDLE hmf; /* Global memory handle to the metafile */
RECT bbox; /* Tightly bounding rectangle in metafile units */
DC inch; /* Length of an inch in metafile units */
} PICTINFO, FAR* LPPICTINFO;
/* The following types are pointers to functions with the same arguments
** as those found in an Aldus-standard function. They are necessary to
** make anonymous function calls. */
/* Version 1.0 filter functions */
typedef WORD (FAR PASCAL *PFN_INFO) (short, LPSTR, HANDLE FAR*, HANDLE FAR*);
typedef WORD (FAR PASCAL *PFN_IMPORT) (HDC, LPFILESPEC, LPPICTINFO, HANDLE);
typedef void (FAR PASCAL *PFN_PREF) (HANDLE, HWND, HANDLE, WORD);
/* Version 2.0 filter functions */
typedef WORD (FAR PASCAL *PFN_VER) (DWORD, BOOL FAR *, WORD FAR *,
WORD FAR *);
typedef WORD (FAR PASCAL *PFN_ISMY) (LPFILESPEC);
typedef WORD (FAR PASCAL *PFN_PREF2) (HANDLE, HANDLE, HANDLE FAR *, DWORD, FARPROC, LPFILESPEC);
typedef WORD (FAR PASCAL *PFN_OUTPUT) (HDC, HDC, LPFILESPEC, LPSTR, LPPICTINFO, HANDLE, FARPROC, BOOL);
/* Function declarations for functions local to this application. */
int PASCAL WinMain( HANDLE, HANDLE, LPSTR, int );
long FAR PASCAL MainWndProc( HWND, unsigned, WORD, LONG );
BOOL FAR PASCAL AboutDlgProc( HWND, unsigned, WORD, LONG );
BOOL NEAR ImportFile( HWND );
BOOL NEAR GetExtFilter( void );
HDC NEAR GetPrinterIC( void );
[LISTING TWO]
/****************************************************************************
FILE : Viewer.c
PURPOSE: Graphics file viewer
FUNCTIONS:
WinMain() - calls initialization function, processes message loop
MainWndProc() - processes messages
ImportFile() - Converts graphics file to Windows Metafile
GetExtFilter() - Determines correct filter for chosen file
GetPrinterIC() - Determines current printer
AboutDlgProc() - processes messages for "About" dialog box
COMMENTS:
(C) 1992, Evangelo Prodromou. All rights reserved.
****************************************************************************/
/* include the general Windows header and the header for this application. */
#include "windows.h"
#include "viewer.h"
/* These strings are used repeatedly. */
char szAppName[ ] = "GraphicViewer";
char szClassName[ ] = "ViewerWClass";
char szMenuName[ ] = "ViewerMenu";
char szString[ STRINGSIZE ]; /* General use string. */
char szFilter[ IBMFNSIZE ]; /* full path name of import filter. */
/* Info struct of the imported metafile. */
PICTINFO PictInfo = { NULL,0,0,0,0,0 };
/* Spec struct for file to import. */
FILESPEC FileSpec = { 0,0,0,0,0,0L,NULL };
HANDLE hInst; /* Handle for this instance. */
/***************************************************************************
FUNCTION: WinMain
PURPOSE: Entrance point of application
ARGS: hInstance : handle to this instance.
hPrevInstance : handle to previous instance of the application.
lpCmdLine : command line string
nCmdShow : show full or iconic? Passed to ShowWindow()
COMMENTS: If no previous instance, registers the window class.
Saves this instance handle as a global variable.
Parses command line for a file name to view.
Creates window for this instance.
Shows the window.
Takes and translates messages from the message loop and passes
them on to MainWndProc().
***************************************************************************/
int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg; /* Windows message structure */
WNDCLASS wc; /* Window class structure. */
HWND hMain; /* handle to main window. */
/* If there is no previous instance of the application, fill in the
** window class structure and register the class. */
if (!hPrevInstance)
{
wc.style = NULL;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = (LPSTR) szMenuName;
wc.lpszClassName = (LPSTR) szClassName;
if (!RegisterClass(&wc))
return FALSE;
}
/* Save the instance handle as a global variable. */
hInst = hInstance;
/* Copy the command line argument to the filename field of FileSpec. */
lstrcpy( FileSpec.fullName, lpCmdLine );
/* Create the main window (will send WM_CREATE to the MainWndProc). */
hMain = CreateWindow( szClassName, szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL );
if (!hMain)
return (FALSE);
/* Show the window and update it ( sends WM_PAINT to MainWndProc ). */
ShowWindow(hMain, nCmdShow);
UpdateWindow(hMain);
/* Get window messages for this instance and send them to the MainWndProc.
** Loops until WM_QUIT message is received. */
while ( GetMessage( &msg,NULL,NULL,NULL ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return ( msg.wParam );
}
/***************************************************************************
FUNCTION: MainWndProc
PURPOSE: Processes messages for main window
ARGS: hWnd : handle to main window
message : windows message
wParam : extra message info
lParam : extra message info
MESSAGES: WM_CREATE : If a file was specified on the command line, gets
the correct filter by extension, and tries to
import it. If no file specified, or if no matching
filter is found, asks for a new file.
WM_PAINT : If a file has been imported, displays the
resulting metafile. Otherwise, passes the message
to default.
WM_SIZE : Invalidate whole client area, and repaint.
WM_DESTROY : Terminates program.
WM_COMMAND : IDM_ABOUT : Displays About dialog box.
***************************************************************************/
long FAR PASCAL MainWndProc(HWND hWnd, unsigned message, WORD wParam, LONG lParam)
{
FARPROC lpProc;
BOOL bError;
RECT rc;
switch (message)
{
case WM_CREATE:
/* Assume an error to begin with. */
bError = TRUE;
if ( FileSpec.fullName[0] == '\0' ) /* No filename on command line */
{
lstrcpy( (LPSTR) szString, "No file name specified." );
}
else if ( !GetExtFilter( ) ) /* Unable to find filter */
{
lstrcpy( (LPSTR) szString,
"No filter specified in WIN.INI for file extension." );
}
else if ( !ImportFile( hWnd ) ) /* Unable to import */
{
lstrcpy( (LPSTR) szString, "Unable to import file." );
}
else bError = FALSE; /* Import was a success */
if (bError)
{
MessageBox( hWnd, (LPSTR) szString,
(LPSTR) szAppName, MB_OK | MB_ICONHAND );
DestroyWindow( hWnd );
}
break;
case WM_PAINT: /* Paint window by playing metafile. */
if ( PictInfo.hmf ) /* A file has been imported. */
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint( hWnd, &ps );
SetMapMode( hDC, MM_ANISOTROPIC );
SetWindowExt( hDC, PictInfo.bbox.right - PictInfo.bbox.left,
PictInfo.bbox.bottom - PictInfo.bbox.top );
GetClientRect( hWnd, &rc );
SetViewportExt( hDC, rc.right - rc.left, rc.bottom - rc.top );
SetWindowOrg( hDC, PictInfo.bbox.left, PictInfo.bbox.top );
PlayMetaFile( hDC, PictInfo.hmf );
EndPaint( hWnd, &ps );
}
break;
case WM_SIZE: /* Invalidate, and paint full window. */
GetClientRect( hWnd, &rc );
InvalidateRect( hWnd, &rc, TRUE);
UpdateWindow( hWnd );
break;
case WM_DESTROY: /* Send WM_QUIT message to message loop to end. */
PostQuitMessage( hWnd );
break;
case WM_COMMAND: /* Creates About dialog box. */
if ( wParam == IDM_ABOUT )
{
lpProc = MakeProcInstance( AboutDlgProc, hInst );
DialogBox( hInst, "AboutBox", hWnd, lpProc );
FreeProcInstance( lpProc );
break;
} /* Otherwise, fall through to default. */
default:
return ( DefWindowProc( hWnd, message, wParam, lParam ) );
}
return (NULL);
}
/***************************************************************************
* FUNCTION: ImportFile *
* PURPOSE : Translate a graphic file to a metafile using a filter *
* ARGS : HWND hWnd - handle to main window. *
* RETURN : TRUE if file import is successful, otherwise FALSE. *
* COMMENTS: Loads a filter DLL into memory, and uses it's import *
* functionality to translate a graphic file to a metafile. *
* Uses Aldus-standard interface functions, version 1 or 2. *
***************************************************************************/
BOOL NEAR ImportFile(HWND hWnd)
{
HANDLE hFilter = NULL, hPrefMem = NULL;
WORD wFilterResult = -1;
HDC hPrintIC = NULL;
/* Version 1.0 Filter functions */
PFN_INFO lpfnGetFilterInfo = NULL;
PFN_IMPORT lpfnImportGR = NULL;
PFN_PREF lpfnGetFilterPref = NULL;
/* Version 2.0 Filter functions */
PFN_VER lpfnGetFilterVersion = NULL;
PFN_ISMY lpfnIsThisMyFile = NULL;
PFN_PREF2 lpfnGetFilterPref2 = NULL;
PFN_OUTPUT lpfnOutputGR = NULL;
/* Load appropriate filter. */
hFilter = LoadLibrary( (LPSTR) szFilter );
/* Try to find "GetFilterVersion." */
lpfnGetFilterVersion = GetProcAddress( hFilter, "GetFilterVersion" );
if ( !lpfnGetFilterVersion ) /* This is a v 1.0 filter. */
{
lpfnGetFilterInfo = GetProcAddress( hFilter, "GetFilterInfo" );
if ( lpfnGetFilterInfo )
{
wFilterResult=(*lpfnGetFilterInfo)( 2, NULL, &hPrefMem, NULL );
}
/* Call filter's GetFilterPref function, which creates a "filter preference"
** dialog box to set import options. */
lpfnGetFilterPref = GetProcAddress( hFilter, "GetFilterPref" );
if ( lpfnGetFilterPref )
{
(*lpfnGetFilterPref)( hInst, hWnd, hPrefMem, 1 );
}
/* Call filter's ImportGR function to convert the file to a Windows
** metafile (information is stored in FileSpec). */
lpfnImportGR = GetProcAddress( hFilter, "ImportGR" );
if ( lpfnImportGR )
{
hPrintIC = GetPrinterIC();
wFilterResult = (*lpfnImportGR)( hPrintIC, &FileSpec, &PictInfo, hPrefMem );
}
}
else /* This is a v. 2.0 or higher filter. */
{
/* Ensure that current file is compatible with current filter. */
lpfnIsThisMyFile = GetProcAddress( hFilter, "IsThisMyFile" );
if ( lpfnIsThisMyFile )
{
(*lpfnIsThisMyFile) ( &FileSpec );
}
/* Get user's import preferences. */
lpfnGetFilterPref2 = GetProcAddress( hFilter, "GetFilterPref" );
if (lpfnGetFilterPref2)
{
wFilterResult = (*lpfnGetFilterPref2) ( hInst, hWnd, &hPrefMem, FileSpec.fType, NULL, &FileSpec);
}
/* Convert chosen file to a metafile. */
lpfnOutputGR = GetProcAddress( hFilter, "OutputGR" );
if (lpfnOutputGR)
{
hPrintIC = GetPrinterIC();
wFilterResult = (*lpfnOutputGR) ( NULL, hPrintIC,
&FileSpec, NULL, &PictInfo, hPrefMem, NULL, FALSE);
}
}
/* Free the memory allocated to the filter DLL and the preference memory.*/
FreeLibrary( hFilter );
GlobalFree( hPrefMem );
/* Set the window title to the file name, or return false. */
if ( wFilterResult == 0 )
{
SetWindowText( hWnd, FileSpec.fullName );
return TRUE;
}
else
{
return FALSE;
}
}
/***************************************************************************
* FUNCTION: GetExtFilter *
* PURPOSE : Get filename of filter appropriate for current file. *
* ARGS : none *
* RETURN : TRUE if able to find filter, otherwise FALSE. *
* COMMENTS: Gets all filter names listed under [GraphicViewer] *
* heading in WIN.INI. Checks which one entry supports *
* files with the same extension as FileSpec.fullName. *
***************************************************************************/
BOOL NEAR GetExtFilter( void )
{
PSTR pDesc, pExt, pSupExt;
int nLen = lstrlen( FileSpec.fullName );
/* Set pExt to last char in FileSpec.fullName. */
if (!nLen) return FALSE;
pExt = FileSpec.fullName + nLen - 1;
/* decrement to character after period ('.'). */
while ( *(pExt-1) != '.' )
{
pExt--;
if ( pExt == FileSpec.fullName ) return FALSE;
}
/* get all profile string entries (description of filter). */
nLen = GetProfileString( szAppName, NULL, NULL, szString, STRINGSIZE );
/* start with the first description. */
pDesc = szString;
/* while we still have a string to check... */
while ( pDesc < szString + nLen )
{
/* get the entry for this filter
("[filter file name],[ext]") */
GetProfileString( (LPSTR) szAppName, (LPSTR) pDesc,
NULL, (LPSTR) szFilter, IBMFNSIZE );
/* if one exists, and its extension matches the file extension... */
pSupExt = szFilter + lstrlen( (LPSTR) szFilter) - 1;
while ( *( pSupExt - 1 ) != ',' )
{
pSupExt--;
if (pSupExt == szFilter) return FALSE;
}
if( lstrcmpi( (LPSTR) pExt, (LPSTR) pSupExt ) == 0 )
{
*(pSupExt-1) = '\0';
return TRUE;
}
else
{
/* move on to next filter. */
pDesc += lstrlen( (LPSTR) pDesc ) + 1;
}
}
/* if we get here, we couldn't find one. Make sure szFilter is blank.*/
szFilter[0] = '\0';
/* Report failure. */
return FALSE;
}
/***************************************************************************
* FUNCTION: GetPrinterIC *
* PURPOSE : Get information context for active print device. *
* ARGS : none *
* RETURN : handle to printer's information context or NULL if fail. *
* COMMENTS: Gets device description from [windows] heading in *
* WIN.INI. Breaks down the description into device name, *
* driver name, and output port. Uses CreateIC() to get *
* an information context. *
***************************************************************************/
HDC GetPrinterIC( void )
{
int nLen;
PSTR pDevice, pDriver, pOutput;
HDC hPrintIC = NULL;
/* Get the information on the current printer, listed under "windows" in
** WIN.INI as "device=[device name],[driver],[output port]". */
nLen = GetProfileString("windows", "device", NULL,(LPSTR) szString, STRINGSIZE);
/* Break it down into device name, driver name, output port. */
if ( nLen )
{
/* The device name is the beginning of the string. */
pDevice = szString;
/* The driver name comes right after the first comma ','. */
pDriver = szString;
while ( ( *pDriver != ',' ) )
{
pDriver++;
if ( pDriver >= szString + nLen ) return NULL;
}
*pDriver = '\0'; pDriver++;
/* The output port name comes right after the second comma ','. */
pOutput = pDriver;
while ( ( *pOutput != ',' ) )
{
pOutput++;
if ( pOutput >= szString + nLen ) return NULL;
}
*pOutput = '\0'; pOutput++;
/* Create an information context for this device. */
hPrintIC = CreateIC( (LPSTR) pDriver, (LPSTR) pDevice,
(LPSTR) pOutput, NULL );
}
return ( hPrintIC );
}
/***************************************************************************
* FUNCTION: AboutDlgProc *
* PURPOSE : Handles messages for AboutBox dialog box. *
* ARGS : Standard callback arguments. *
* RETURN : N/A. *
* COMMENTS: Closes AboutBox when OK button, Enter or ESC are pressed.*
***************************************************************************/
BOOL FAR PASCAL AboutDlgProc(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
{
switch (message)
{
case WM_INITDIALOG: /* Beginning. No functionality. */
return (TRUE);
case WM_COMMAND:
switch (wParam)
{
case IDOK: /* OK or Enter were pressed. */
case IDCANCEL: /* Esc was pressed. */
EndDialog(hDlg, TRUE);
return (TRUE);
}
break;
}
return (FALSE);
}